<template>
  <pre class="sql-highlighter" v-html="highlightedContent"></pre>
</template>

<script setup>
import { computed } from 'vue'
import { getAllKeywords } from './utils/sqlKeywords'

const props = defineProps({
  content: {
    type: String,
    default: ''
  }
})

// 计算高亮后的内容
const highlightedContent = computed(() => {
  if (!props.content) {
    return ''
  }

  try {
    // 使用更简单的方法：按行处理，然后使用分词分析
    // 这样可以避免正则表达式替换的嵌套问题
    return highlightByTokens(props.content)
  } catch (error) {
    console.error('SQL高亮错误:', error)
    // 出错时至少显示原始内容（安全转义）
    return escapeHtml(props.content)
  }
})

// 安全转义HTML
function escapeHtml(text) {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
}

// 简单的SQL标记分析器
function highlightByTokens(text) {
  // 获取SQL关键词列表（全部大写）
  const keywords = getAllKeywords()
  
  // 先转义HTML特殊字符
  const escapedText = escapeHtml(text)
  
  // 按行分割
  const lines = escapedText.split('\n')
  const resultLines = []
  
  // 针对每一行进行处理
  for (const line of lines) {
    // 检测注释
    if (line.trim().startsWith('--')) {
      resultLines.push(`<span class="sql-comment">${line}</span>`)
      continue
    }
    
    // 分词：把一行文本分解为标记
    let result = ''
    let currentToken = ''
    let inString = false
    let stringChar = ''
    
    // 遍历每个字符
    for (let i = 0; i < line.length; i++) {
      const char = line[i]
      
      // 字符串处理
      if ((char === "'" || char === '"') && (i === 0 || line[i-1] !== '\\')) {
        if (!inString) {
          // 开始字符串
          if (currentToken) {
            result += processToken(currentToken)
            currentToken = ''
          }
          inString = true
          stringChar = char
          currentToken += char
        } else if (char === stringChar) {
          // 结束字符串
          currentToken += char
          result += `<span class="sql-string">${currentToken}</span>`
          currentToken = ''
          inString = false
        } else {
          // 字符串内的另一种引号
          currentToken += char
        }
        continue
      }
      
      if (inString) {
        currentToken += char
        continue
      }
      
      // 分隔符处理（空格、逗号、括号等）
      if (/[\s,.()=<>+\-*/%]/.test(char)) {
        if (currentToken) {
          result += processToken(currentToken)
          currentToken = ''
        }
        
        // 操作符高亮
        if (/[=<>+\-*/%]/.test(char)) {
          result += `<span class="sql-operator">${char}</span>`
        } else {
          result += char
        }
      } else {
        currentToken += char
      }
    }
    
    // 处理行末尾的令牌
    if (currentToken) {
      if (inString) {
        result += `<span class="sql-string">${currentToken}</span>`
      } else {
        result += processToken(currentToken)
      }
    }
    
    resultLines.push(result)
  }
  
  return resultLines.join('<br>')
  
  // 处理单个令牌
  function processToken(token) {
    // 处理关键字（不区分大小写）
    if (keywords.includes(token.toUpperCase())) {
      return `<span class="sql-keyword">${token}</span>`
    }
    
    // 处理数字
    if (/^\d+(\.\d+)?$/.test(token)) {
      return `<span class="sql-number">${token}</span>`
    }
    
    // 默认为标识符
    return `<span class="sql-identifier">${token}</span>`
  }
}
</script>

<style scoped>
.sql-highlighter {
  padding: 8px 12px;
  font-family: 'JetBrains Mono', 'Consolas', 'Monaco', monospace;
  font-size: 14px;
  line-height: 20px;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
  overflow: visible;
}

:deep(.sql-keyword) {
  color: #7c3aed;
  font-weight: 600;
}

:deep(.sql-string) {
  color: #059669;
}

:deep(.sql-number) {
  color: #dc2626;
}

:deep(.sql-comment) {
  color: #6b7280;
  font-style: italic;
}

:deep(.sql-operator) {
  color: #ea580c;
  font-weight: 500;
}

:deep(.sql-identifier) {
  color: #374151;
}
</style> 